package com.gitee.apanlh.util.net.http.handler;

import com.gitee.apanlh.exp.HttpException;
import com.gitee.apanlh.util.net.http.HttpBodyTypeEnum;
import com.gitee.apanlh.util.net.http.HttpClient;
import com.gitee.apanlh.util.net.http.HttpRequest;
import com.gitee.apanlh.util.net.http.handler.body.HttpBodyFormDataParseStrategy;
import com.gitee.apanlh.util.net.http.handler.body.HttpBodyFormParseStrategy;
import com.gitee.apanlh.util.net.http.handler.body.HttpBodyJsonParseStrategy;
import com.gitee.apanlh.util.net.http.handler.body.HttpBodyParseContext;
import com.gitee.apanlh.util.net.http.handler.body.HttpBodyPathVariableParseStrategy;
import com.gitee.apanlh.util.net.http.handler.body.HttpBodyQueryParamParseStrategy;

import java.util.List;

/**
 * 	HTTP请求拦截器责任链，按照顺序执行HTTP请求拦截器
 * 	<br>在HTTP请求发送前执行
 * 
 * 	@author Pan
 */
public class HttpRequestInterceptorChain extends HttpInterceptorChain {
	
	/** 请求体解析上下文 */
	private static final HttpBodyParseContext BODY_PARSE_CONTEXT = initContext();
	
	/** 默认实现拦截器 */
	private static final HttpRequestBodyChain 				HTTP_REQUEST_BODY_CHAIN 				= 	new HttpRequestBodyChain();
	private static final HttpConnectionConfigureChain 		HTTP_CONNECTION_CONFIGURE_CHAIN 		= 	new HttpConnectionConfigureChain();
	private static final HttpContentTypeConfigureChain 		HTTP_CONTENT_TYPE_CONFIGURE_CHAIN 		= 	new HttpContentTypeConfigureChain();
	private static final HttpContentLengthConfigureChain 	HTTP_CONTENT_LENGTH_CONFIGURE_CHAIN 	= 	new HttpContentLengthConfigureChain();
	private static final HttpHeaderConfigureChain 			HTTP_HEADER_CONFIGURE_CHAIN 			= 	new HttpHeaderConfigureChain();
	
	/**
	 * 	构造函数-默认初始化拦截链
	 * 	<br>有序集合
	 * 	<br><br>在HTTP参数解析后执行
	 * 
	 * 	@author Pan
	 */
	HttpRequestInterceptorChain() {
		super();
	}
	
	/**
	 * 	构造函数-添加一个HTTP拦截器
	 * 	<br>继承父类
	 * 	
	 * 	@author Pan
	 * 	@param 	interceptor  需要添加的拦截器
	 */
	public HttpRequestInterceptorChain(HttpInterceptor interceptor) {
		super(interceptor);
	}
	
	/**	
	 * 	构造函数-初始化链
	 * 	<br>继承父类
	 * 
	 * 	@author Pan
	 * 	@param 	interceptors	一个或多个链
	 */
	public HttpRequestInterceptorChain(List<HttpInterceptor> interceptors) {
		super(interceptors);
	}
	
	/**
	 * 	执行HTTP请求拦截器责任
	 * 	<br>返回null则终止执行接下来所有链
	 * 	<br>在HTTP请求发送前执行
	 * 
	 * 	@param 	httpRequest 	HTTP请求对象
	 * 	@param 	client			HTTP客户端
	 * 	@return HttpRequest		HTTP请求对象
	 * 	@throws HttpException 	处理异常，则抛出该异常
	 */
	@Override
	public HttpRequest proceed(HttpRequest httpRequest, HttpClient client) throws HttpException {
		while (super.hasNext()) {
			HttpRequest proceed = super.proceed(httpRequest, client);
			//	如果返回null停止执行
			if (proceed == null) {
				break;
			}
		}
		return httpRequest;
	}
	
	@Override
	public void loadExecute() throws HttpException {
		//	先解析请求体，避免pathVariable及queryParam顺序问题
		super.load(HTTP_REQUEST_BODY_CHAIN);
		super.load(HTTP_CONNECTION_CONFIGURE_CHAIN);
		super.load(HTTP_CONTENT_TYPE_CONFIGURE_CHAIN);
		super.load(HTTP_CONTENT_LENGTH_CONFIGURE_CHAIN);
		super.load(HTTP_HEADER_CONFIGURE_CHAIN);
	}
	
	/**	
	 * 	静态初始化HTTPRequestBody请求解析上下文
	 * 	
	 * 	@author Pan
	 * 	@return	HttpBodyParseContext
	 */
	static HttpBodyParseContext initContext() {
		//	初始化HTTPRequest请求解析
		HttpBodyParseContext bodyParseContext = new HttpBodyParseContext();
		bodyParseContext.register(new HttpBodyQueryParamParseStrategy(), 	HttpBodyTypeEnum.QUERY_PARAMS);
		bodyParseContext.register(new HttpBodyFormParseStrategy(), 			HttpBodyTypeEnum.FORM);
		bodyParseContext.register(new HttpBodyFormDataParseStrategy(), 		HttpBodyTypeEnum.FORM_DATA);
		bodyParseContext.register(new HttpBodyJsonParseStrategy(), 			HttpBodyTypeEnum.JSON);
		bodyParseContext.register(new HttpBodyPathVariableParseStrategy(), 	HttpBodyTypeEnum.PATH_VARIABLE);
		return bodyParseContext;
	}
	
	/**	
	 * 	获取请求解析上下文
	 * 
	 * 	@author Pan
	 * 	@return	HttpBodyParseContext
	 */
	public static HttpBodyParseContext getBodyParseContext() {
		return BODY_PARSE_CONTEXT;
	}
}
